package com.zhuhjay;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Property;
import com.zhuhjay.common.base.controller.BaseController;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.function.Function;

/**
 * @author ZhuHJay
 * @date 2023/2/25 21:45
 */
public class MybatisPlusGenerator {
    /**
     * service,mapper,entity文件输出路径
     */
    private static final String OUT_DIR_PATH =
            "G:\\0Pro0Workspace\\ToolsBoot\\GenericBoot-Server\\service\\%s" +
                    "/src/main/java";
    /**
     * 需定制的数据信息
     */
    private static final String HOST = "localhost";
    private static final String PORT = "3306";
    private static final String DATABASE = "tools";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "123456";


    /**
     * 数据库连接信息
     */
    private static final String MYSQL_URL_PREFIX = "jdbc:mysql://";
    private static final String MYSQL_URL_SUFFIX =
            "?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC";

    public static void main(String[] args) {
        moduleName = scannerNext("生成的子模块名 ed: system");
        FastAutoGenerator
                .create(getDataSourceConfig())
                .globalConfig(MybatisPlusGenerator::getGlobalConfig)
                .packageConfig(MybatisPlusGenerator::getPackageConfig)
                .strategyConfig(MybatisPlusGenerator::getStrategyConfig)
                .templateConfig(MybatisPlusGenerator::getTemplateConfig)
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .execute();
    }

    protected static DataSourceConfig.Builder getDataSourceConfig() {
        return new DataSourceConfig.Builder(MYSQL_URL_PREFIX + HOST + ':' + PORT + '/' + DATABASE + MYSQL_URL_SUFFIX, USERNAME, PASSWORD);
    }

    protected static void getGlobalConfig(Function<String, String> scanner, GlobalConfig.Builder builder) {
        builder.outputDir(String.format(OUT_DIR_PATH, moduleName)) // 指定输出目录
                .disableOpenDir()
                .author("ZhuHJay") // 	作者名
                .enableSwagger() // 开启 swagger 模式
                .dateType(DateType.ONLY_DATE) // 时间策略
                .commentDate("yyyy-MM-dd") // 注释日期
                .build();
    }

    protected static void getPackageConfig(Function<String, String> scanner, PackageConfig.Builder builder) {
        builder.parent(String.format("com.zhuhjay.service.%s", moduleName)) // 父包名
                //.moduleName(scanner.apply("请输入存放的父包模块名 eg: system")) // 父包模块名
                .entity("model.entity") // Entity 包名
                .service("service") // Service 包名
                .serviceImpl("service.impl") // Service Impl 包名
                .mapper("mapper") // Mapper 包名
                .controller("controller") // Controller 包名
                .build();
    }

    protected static void getTemplateConfig(TemplateConfig.Builder builder) {
        builder
                .entity("/templates/entity.java") // 设置实体模板路径(JAVA)
                .service("/templates/service.java") // 设置 service 模板路径
                .serviceImpl("/templates/serviceImpl.java") // 设置 serviceImpl 模板路径
                .controller("/templates/controller.java") // 设置 controller 模板路径
                .build();
    }

    protected static void getStrategyConfig(Function<String, String> scanner, StrategyConfig.Builder builder) {
        builder.enableCapitalMode() // 	开启大写命名
                .enableSkipView() // 开启跳过视图
                .disableSqlFilter() // 禁用 sql 过滤
                .addInclude(getTables(scanner.apply("请输入表名，多个英文逗号分隔？所有输入 all"))) // 增加表匹配(内存过滤)
                // 实体设置
                .entityBuilder()
                .enableLombok()
                .enableChainModel()
                //.enableTableFieldAnnotation()
                .idType(IdType.ASSIGN_UUID)
                .addTableFills(new Property("createTime", FieldFill.INSERT))
                .addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE))
                // 控制器设置
                .controllerBuilder()
                .superClass(BaseController.class)
                .enableRestStyle()
                // 业务设置
                .serviceBuilder()
                .formatServiceFileName("%sService")
                .formatServiceImplFileName("%sServiceImpl")
                .build();
    }

    // 处理 all 情况
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }

    /**
     * 读取控制台输入内容
     */
    private static final Scanner scanner = new Scanner(System.in);
    /**
     * 子模块名
     */
    private static String moduleName;

    /**
     * 控制台输入内容读取并打印提示信息
     */
    private static String scannerNext(String message) {
        System.out.println(message);
        String nextLine = scanner.nextLine();
        if (StringUtils.isBlank(nextLine)) {
            // 如果输入空行继续等待
            return scanner.next();
        }
        return nextLine;
    }
}
